package com.yxc.easyexceldemo.convert;

import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.converters.ReadConverterContext;
import com.alibaba.excel.converters.WriteConverterContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.yxc.easyexceldemo.annotations.EasyExcelEnumDataSource;
import com.yxc.easyexceldemo.const_enum.MEnum;

import java.lang.reflect.Field;

/**
 * 枚举类的转换
 *
 * @author: YXC
 * @time: 2022/11/16 15:38
 **/
public class EnumDataSourceConvert implements Converter<Integer> {


    @Override
    public Class<?> supportJavaTypeKey() {
        return Integer.class;
    }

    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;
    }

    @Override
    public Integer convertToJavaData(ReadConverterContext<?> context) throws Exception {
        Field field = getField(context);

        EasyExcelEnumDataSource dataSource = field.getAnnotation(EasyExcelEnumDataSource.class);
        checkDataSource(dataSource);
        if (!dataSource.enumClass().equals(MEnum.class)) {
            // 优先使用MEnum
            return (Integer) MEnum.staticGetByName(dataSource.enumClass(), context.getReadCellData().getStringValue()).getCode();
        }
        EasyExcelEnumDataSource.EasyExcelEnumData easyExcelEnumData;
        try {
            easyExcelEnumData = dataSource.data().newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            throw new InstantiationException("没有空参构造器!");
        }
        return (Integer) easyExcelEnumData.getCodeByName(context.getReadCellData().getStringValue());
    }

    @Override
    public WriteCellData<?> convertToExcelData(WriteConverterContext<Integer> context) throws Exception {
        Field field = getField(context);

        EasyExcelEnumDataSource dataSource = field.getAnnotation(EasyExcelEnumDataSource.class);
        checkDataSource(dataSource);
        if (!dataSource.enumClass().equals(MEnum.class)) {
            // 优先使用MEnum
            return new WriteCellData<>(MEnum.staticGetByCode(dataSource.enumClass(), context.getValue()).getName());
        }
        EasyExcelEnumDataSource.EasyExcelEnumData easyExcelEnumData;
        try {
            easyExcelEnumData = dataSource.data().newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            throw new InstantiationException("没有空参构造器!");
        }
        String name = (String)easyExcelEnumData.getNameByCode(context.getValue());
        return new WriteCellData<>(name);
    }

    private Field getField(WriteConverterContext<Integer> context) {
        return context.getContentProperty().getField();
    }

    private Field getField(ReadConverterContext<?> context) {
        return context.getContentProperty().getField();
    }

    private void checkDataSource(EasyExcelEnumDataSource dataSource) {
        if (dataSource == null) {
            throw new IllegalStateException("使用EnumDataSourceConvert转换必须添加EasyExcelEnumDataSource注解");
        }
        if (dataSource.enumClass().equals(MEnum.class) && dataSource.data().equals(EasyExcelEnumDataSource.EasyExcelEnumData.class)) {
            throw new IllegalStateException("EasyExcelEnumDataSource注解enumClass属性和data属性必须使用一个");
        }
    }
}
